/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.bff.designtime.generator.metadatacompile;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.collection.GspElementCollection;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewModelElement;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.formserver.viewmodel.collection.VMElementCollection;
import com.inspur.edp.jittojava.context.JitContext;

import java.util.HashMap;
import java.util.Map;

public
class VmObjectCoincidenceCheck extends VmCoincidenceCheck {

  protected IGspCommonObject viewModelObject;

  public VmObjectCoincidenceCheck(JitContext context, IGspCommonObject viewObject,
      HashMap<String, GspBusinessEntity> relatedBizEntityDic) {
    super(context);
    this.viewModelObject = viewObject;
    this.relatedBizEntityDic = relatedBizEntityDic;
  }

  //检查节点: 节点编号修改

  protected String checkCurrentObject() {
    Map<String,Object> bizObjectMessage = getViewObjectRelatedBizEntityObject(viewModelObject);
    GspBusinessEntity bizEntity = (GspBusinessEntity)bizObjectMessage.get("GspBusinessEntity");
    GspBizEntityObject bizEntityObject = (GspBizEntityObject) bizObjectMessage.get("GspBizEntityObject");
    //获取获取映射的BE
    if (bizEntityObject == null) {
      return this.exceptionMessage.toString();
    }
//    if (!viewModelObject.getCode().equals(bizEntityObject.getCode())) {
//      this.exceptionMessage.append(CheckCoincidenceException.throwVoNodeCodeNotEqualException(this.viewModel,this.viewModelObject,bizEntity,bizEntityObject));
//    }
    //比较节点上的字段集合，（通过映射关系找到BE上字段，需要关联BE信息）
    checkElementCollection((VMElementCollection) viewModelObject.getContainElements());

    return returnExceptionMessage();
  }

  protected String returnExceptionMessage() {
    if (this.exceptionMessage == null || this.exceptionMessage.toString().equals("")) {
      return null;
    }
    return this.exceptionMessage.toString();
  }


  protected void checkElementCollection(GspElementCollection vmCollection) {
    if (vmCollection == null || vmCollection.size() == 0) {
      return;
    }
    for (IGspCommonField vmElement : vmCollection) {
      if (vmElement.getIsVirtual()) {
        continue;
      }
      checkMappingElement((GspViewModelElement)vmElement);
    }
  }

  //找到关联BE上映射字段
  protected IGspCommonElement getRelativeBeElement(IGspCommonField vmElement,
      GspBizEntityObject bizEntityObject) {
    if (!(vmElement instanceof GspViewModelElement)) {
      this.exceptionMessage.append(CheckCoincidenceException.throwElementException(this.viewModel,this.viewModelObject,vmElement,"数据类型异常"));
      return null;
    }
    String targetElementId = ((GspViewModelElement) vmElement).getMapping().getTargetElementId();
    if (bizEntityObject.findElement(targetElementId) == null) {
      this.exceptionMessage.append(CheckCoincidenceException.throwElementException(this.viewModel,this.viewModelObject,vmElement,"在BE上没有找到VO字段对应的BE字段"));
      return null;
    }
    return bizEntityObject.findElement(targetElementId);
  }

  //获取Mapping的BE节点
  protected Map<String,Object> getViewObjectRelatedBizEntityObject(IGspCommonObject viewObject) {
    Map<String,Object> returnMap = new HashMap<String, Object>();
    if (((GspViewObject) viewObject).getMapping() == null) {
      this.exceptionMessage.append(CheckCoincidenceException.throwVmObjectMappingException(this.viewModel,viewObject));
      return null;
    }
    String relateObjId = ((GspViewObject) viewObject).getMapping().getTargetObjId();
    GspBusinessEntity businessEntity = getViewObjectRelatedBizEntity(viewObject);

    IGspCommonObject commonObject = businessEntity.findObjectById(relateObjId);
    if (commonObject == null || !(commonObject instanceof GspBizEntityObject)) {
      this.exceptionMessage.append(CheckCoincidenceException.throwBizEntityNotFindException(this.viewModel,viewObject));
    }
    returnMap.put("GspBusinessEntity",businessEntity);
    returnMap.put("GspBizEntityObject",commonObject);
    return returnMap;
  }

  protected void checkMappingElement(GspViewModelElement vmField) {
    if (vmField.getMapping() == null) {
      this.exceptionMessage.append(CheckCoincidenceException
          .throwElementException(this.viewModel,this.viewModelObject,vmField,"VO字段无法找到对应的BE字段！"));
      return;
    }

    GspBusinessEntity businessEntity = getBizEntityByMetadataId(
        vmField.getMapping().getTargetMetadataId(),this.viewModelObject);
    if (businessEntity == null) {
      this.exceptionMessage.append(CheckCoincidenceException
          .throwElementException(this.viewModel,this.viewModelObject,vmField,"VO字段无法找到对应的BE字段！"));
      return;
    }

    IGspCommonObject findObject = businessEntity
        .findObjectById(vmField.getMapping().getTargetObjectId());

    if (findObject == null || !(findObject instanceof GspBizEntityObject)) {
      this.exceptionMessage.append(CheckCoincidenceException
          .throwElementException(this.viewModel,this.viewModelObject,vmField,"VO字段无法找到对应的BE字段"));
      return;
    }
    IGspCommonElement commonElement = findObject
        .findElement(vmField.getMapping().getTargetElementId());

    if (commonElement == null) {
      this.exceptionMessage.append(CheckCoincidenceException
          .throwElementException(this.viewModel,this.viewModelObject,vmField,"VO字段无法找到对应的BE字段"));
      return;
    }
    VmElementCoincidenceCheck vmElementCheck = new VmElementCoincidenceCheck(this.jitContext,
        findObject, this.relatedBizEntityDic, vmField,businessEntity,(GspBizEntityObject)findObject, commonElement);
    //检查字段
    vmElementCheck.checkElement();
    if(vmElementCheck.exceptionMessage != null &&  vmElementCheck.exceptionMessage.length() != 0){
      this.exceptionMessage.append(vmElementCheck.exceptionMessage);
    }
  }

}
